﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using AIMLbot;
using Matrix;
using Matrix.Xmpp;
using Matrix.Xmpp.Client;
using EventArgs = System.EventArgs;
using Message = Matrix.Xmpp.Client.Message;

namespace ClientDemo
{
    public partial class FrmChat : UserControl
    {
        private XmppClient _xmppClient;
        private Jid _jid;
        private readonly string _nickname;
        private Bot myBot;
        private User myUser;
        public FrmAIML myAIML;

        public FrmChat(Jid jid, XmppClient con, string nickname)
        {
            this._jid = jid;
            this._xmppClient = con;
            this._nickname = nickname;
            this.myBot = new Bot();
            this.myBot.loadSettings();
            this.myUser = new User(_jid.Bare.ToLower(), this.myBot);
            this.myBot.WrittenToLog += new Bot.LogMessageDelegate(myBot_WrittenToLog);
            this.myAIML = new FrmAIML();
            this.myAIML.listBox1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.listBox1_MouseDoubleClick);
            this.myAIML.Dock = DockStyle.Fill;

            InitializeComponent();

            Text = "Chat with " + nickname;

            Util.ChatForms.Add(_jid.Bare.ToLower(), this);

            // Setup new Message Callback
            con.MessageFilter.Add(jid, new BareJidComparer(), OnMessage);
        }

        private void myBot_WrittenToLog()
        {
            this.rtfChat.SelectionColor = Color.Black;
            this.rtfChat.Text += this.myBot.LastLogMessage + Environment.NewLine;
            this.rtfChat.ScrollToCaret();
        }

        private void OutgoingMessage(Message msg)
        {
            this.rtfChat.SelectionColor = Color.Blue;
            this.rtfChat.AppendText("Me said: ");
            this.rtfChat.SelectionColor = Color.Black;
            this.rtfChat.AppendText(msg.Body);
            this.rtfChat.AppendText("\r\n");
            this.rtfChat.ScrollToCaret();
        }

        private bool flag_AIML = false;
        public void IncomingMessage(Message msg)
        {
            this.rtfChat.SelectionColor = Color.Red;
            this.rtfChat.AppendText(_nickname + " said: ");
            this.rtfChat.SelectionColor = Color.Black;
            this.rtfChat.AppendText(msg.Body);
            this.rtfChat.AppendText("\r\n");
            this.rtfChat.ScrollToCaret();
            if (this.flag_AIML)   processInputFromUser(msg.Body);
        }

        private void OnMessage(object sender, MessageEventArgs e)
        {
            if (e.Message.Body != null)
                IncomingMessage(e.Message);
        }

        private void sendButton_Click(object sender, EventArgs e)
        {
            if (rtfSend.Text.Length < 1) return;
            var msg = new Message { Type = MessageType.chat, To = _jid, Body = rtfSend.Text };

            _xmppClient.Send(msg);
            OutgoingMessage(msg);
            rtfSend.Text = "";
        }

        private bool flag_ParentChanged = true;
            
        private void FrmChat_ParentChanged(object sender, EventArgs e)
        {
            if (this.flag_ParentChanged) { this.flag_ParentChanged = !this.flag_ParentChanged; return; }
            Util.ChatForms.Remove(this._jid.Bare.ToLower());
            _xmppClient.MessageFilter.Remove(this._jid);
            _xmppClient = null;
        }

        private void loadAIML_Click(object sender, EventArgs e)
        {
            if (!this.flag_AIML)
            {
                AIMLbot.Utils.AIMLLoader loader = new AIMLbot.Utils.AIMLLoader(this.myBot);
                this.myBot.isAcceptingUserInput = false;
                loader.loadAIML(this.myBot.PathToAIML);
                this.myBot.isAcceptingUserInput = true;
            }          
            this.flag_AIML = true;
        }

        private void processInputFromUser(string rawInput)
        {
            if (this.flag_AIML)
            {
                Request myRequest = new Request(rawInput, this.myUser, this.myBot);
                Result myResult = this.myBot.Chat(myRequest);

                this.myAIML.listBox1.Items.Clear();
                this.myAIML.listBox1.Items.Add(myResult.Output);
                this.myAIML.listBox1.Show();
            }
        }

        private void listBox1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            string getString = this.myAIML.listBox1.SelectedItem.ToString();
            this.rtfSend.Clear();
            this.rtfSend.Text += getString;
        }

        private void FrmChat_MouseClick(object sender, MouseEventArgs e)
        {
            myAIML.BringToFront();
        }
    }
}
